/**   
 * @Title: QuartzUtil.java 
 * @Package com.cyber.quartz 
 * @Description: 
 * @author cssuger@163.com   
 * @date 2016年12月15日 下午5:29:17 
 * @version V1.0   
 */
package cn.com.ytst.data.integration.manager.job;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;
import com.ytst.framework.common.StringTools;
import com.ytst.framework.common.tools.JsonUtil;

/**
 * @ClassName: QuartzUtil
 * @Description: quartz 数据库持久化，1 注意在持久化时，如果job名称存在，需要进行判断。
 * 1目前 发现还存在一点小瑕疵：在修改属性的时候，居然不起作用，
 * 2删除该job的时候需要涉及三张表
 * SELECT * FROM qrtz_job_details

SELECT * FROM qrtz_cron_triggers

SELECT * FROM  qrtz_triggers
删除顺序从后往前删除
 * @author cssuger@163.com
 * @date 2016年12月15日 下午5:29:17
 */
@Component("quartzManager")
public class QuartzManager {

	
	private  final Logger logger = LoggerFactory.getLogger(QuartzManager.class);
	
	
	@Autowired
	private Scheduler scheduler;
	
	
	

	
	
     /**
      * 
      * @Title: buliderScheduler 
      * @Description: 构建任务调度 
      * @param @param jobName job名称可以是url 也可以是一个类
      * @param @param desc job描述
      * @param @param clazz job执行的类型
      * @param @param cronexpress作业时间表达式
      * @param @param methodName 方法名称
      * @param @return    设定文件 
      * @return Scheduler    返回类型 
      * @throws
      */
	public void addTask(String jobName, String desc,
			Class<? extends Job> clazz, String cronexpress, String methodName,Object  object,String prarms) {
		try {
			
			JobDetail jobDetail = JobBuilder.newJob(clazz).withDescription(desc).withIdentity(jobName, TaskManager.GROUP_NAME).build();
			
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName,TaskManager.GROUP_NAME);
			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
			// 如果不存在trigger,那么重新构建trigger
			if (null == trigger) {
				TaskManager taskManager = new TaskManager(jobName, clazz, desc,cronexpress);
				taskManager.setMethodName(methodName);
				taskManager.setServiceClass(object.getClass().getName());
				taskManager.setObject(object);//bean对象
				taskManager.setPramrms(prarms);
				jobDetail.getJobDataMap().put("task", JsonUtil.objectToJson(taskManager));
				jobDetail.getJobDataMap().put("object", object);
				if(!StringTools.isBlank(prarms)) {
					jobDetail.getJobDataMap().put("prarms", prarms);
				}
				CronScheduleBuilder cronBuilder = CronScheduleBuilder.cronSchedule(cronexpress);
				
				trigger = TriggerBuilder.newTrigger().withSchedule(cronBuilder).startNow().withIdentity(jobName, TaskManager.GROUP_NAME).build();
				
				scheduler.scheduleJob(jobDetail, trigger);
			} else {
				// 重新装入表达式
				TaskManager taskManager = new TaskManager(jobName, clazz, desc,cronexpress);
				taskManager.setMethodName(methodName);
				taskManager.setObject(object);
				taskManager.setPramrms(prarms);
				jobDetail.getJobDataMap().put("task", JsonUtil.objectToJson(taskManager));
				jobDetail.getJobDataMap().put("object", object);
				if(!StringTools.isBlank(prarms)) {
					jobDetail.getJobDataMap().put("prarms", prarms);
				}
				CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronexpress);
				// 按新的cronExpression表达式重新构建trigger
				trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).startNow().withSchedule(scheduleBuilder).build();
				// 按新的trigger重新设置job执行
				scheduler.rescheduleJob(triggerKey, trigger);
				logger.info("该任务已经存在");
			}
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		
	}

	public void taskStart(){
		
		try {
			scheduler.start();
		} catch (SchedulerException e) {
		
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	* @Title: getTrigger 
	* @Description: 
	* @param @return    设定文件 
	* @return Trigger    返回类型 
	* @throws
	 */
	public Trigger getTrigger(String triggernme) {
		
		try {
			return scheduler.getTrigger(TriggerKey.triggerKey(triggernme, TaskManager.GROUP_NAME));
			
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 
	 * @Title: deleteTask 
	 * @Description: 删除job 
	 * @param @param taskManage    设定文件 
	 * @return void    返回类型 
	 * @throws
	 */
	public void deleteTask(TaskManager taskManage){
		
		JobKey jobKey = JobKey.jobKey(taskManage.jobName, taskManage.groupName);
		try {
			TriggerKey triggerKey = TriggerKey.triggerKey(taskManage.jobName,TaskManager.GROUP_NAME);
			scheduler.unscheduleJob(triggerKey);
			scheduler.deleteJob(jobKey);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
	
	public void addTask(TaskManager taskManager) {
		if (null == taskManager) {
			throw new NullPointerException("taskManager  is not null");
		}
		 this.addTask(taskManager.jobName, taskManager.jobdesc,
				taskManager.clazz, taskManager.cronexpress,
				taskManager.methodName,taskManager.serviceClass,taskManager.pramrms);
	}
	
	/**
	 * @throws SchedulerException 
	 * 
	* @Title: updateTaskTrigger 
	* @Description: //CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
		//其中withMisfireHandlingInstructionDoNothing——不触发立即执行——等待下次Cron触发频率到达时刻开始按照Cron频率依次执行
		//CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.cronexpress).withMisfireHandlingInstructionDoNothing(); 
	* @param @param task
	* @param @throws Exception    设定文件 
	* @return void    返回类型 
	* @throws
	 */
	public void updateTaskTrigger(TaskManager task) throws SchedulerException  {
		
		CronTrigger trigger = (CronTrigger)scheduler.getTrigger(new TriggerKey(task.jobName, task.groupName));
		scheduler.getJobDetail(JobKey.jobKey(task.jobName, task.groupName)).getJobDataMap().put("task", JsonUtil.objectToJson(task));
		TriggerKey triggerKey = TriggerKey.triggerKey(task.jobName, task.groupName);
		
		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.cronexpress);
		trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).startNow().withSchedule(scheduleBuilder).build();
		scheduler.rescheduleJob(triggerKey, trigger);
	}

	public void resumeTask(TaskManager task) throws SchedulerException {
		
		JobKey jobKey = JobKey.jobKey(task.jobName, task.groupName);
		scheduler.getJobDetail(jobKey).getJobDataMap().put("task", JsonUtil.objectToJson(task));
		scheduler.resumeJob(jobKey);
	}

	/**
	 * 
	 * @Title: pauseTask  
	 * @Description: 停止job  
	 * @param @param task
	 * @param @throws Exception    设定文件  
	 * @return void    返回类型  
	 * @throws
	 */
	public void pauseTask(TaskManager task) throws SchedulerException {
		JobKey jobKey = JobKey.jobKey(task.jobName, task.groupName);
		scheduler.pauseJob(jobKey);
	}

	public List<TaskManager> findExeTaskList() throws SchedulerException {
		
		GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
		Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
		List<TaskManager> jobList = Lists.newArrayList();
		for (JobKey jobKey : jobKeys) {
			List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
			for (Trigger trigger : triggers) {
				TaskManager job = new TaskManager();
				job.jobName = jobKey.getName();
				job.groupName =jobKey.getGroup();
				job.jobdesc ="触发器:" + trigger.getKey();
				Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
				job.setJobStatus(triggerState.name());
				if (trigger instanceof CronTrigger) {
					CronTrigger cronTrigger = (CronTrigger) trigger;
					String cronExpression = cronTrigger.getCronExpression();
					job.cronexpress = cronExpression;
				}
				jobList.add(job);
			}
		}

		return jobList;
	}

	public TriggerState triggerState(String triggerName,String triggerGroup) {
		
		try {
			return scheduler.getTriggerState(TriggerKey.triggerKey(triggerName, triggerGroup));
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	public List<TaskManager> getRunningJob() throws SchedulerException {
		List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
		List<TaskManager> jobList = new ArrayList<>(executingJobs.size());
		for (JobExecutionContext executingJob : executingJobs) {
			TaskManager job = new TaskManager();
			JobDetail jobDetail = executingJob.getJobDetail();
			JobKey jobKey = jobDetail.getKey();
			Trigger trigger = executingJob.getTrigger();
			
			job.jobName = jobKey.getName();
			job.groupName = jobKey.getGroup();
			job.jobdesc = "触发器:" + trigger.getKey();
			Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
			job.setJobStatus(triggerState.name());
			if (trigger instanceof CronTrigger) {
				CronTrigger cronTrigger = (CronTrigger) trigger;
				String cronExpression = cronTrigger.getCronExpression();
				job.cronexpress = cronExpression;
			}
			jobList.add(job);
		}
		return jobList;
	}

	public static void main(String[] args) {
         
	}
}
